package cn.lhjl.day06.note;
/*
* 泛型：是一种未知的数据类型，当我们不知道使用什么数据类型的时候，可以使用泛型。
* 例如例如Arraylist集合在定义的时候，不知道集合存储什么类型数据，所以使用泛型
* E：未知数据类型。
* 创建集合对象时候，就会确定泛型的数据类型
*
* 创建集合对象，不使用泛型
* 好处：
*    集合不使用泛型，默认的类型就是Object类型，可以存储任意类型的数据。
* 弊端：
*    不安全，会引发异常，把每个元素的类型都看作是Object，导致为了用子类特有方法而向下转型，可能导致运行期异常
*
* 创建集合对象，使用泛型
* 好处：
*    1.存储的是什么类型，取出的就是什么类型，避免了类型转换麻烦。
*    2.把运行期异常（代码运行之后抛出的异常），提升到了编译器（写代码时报错）
* 弊端：
*    泛型是什么类型，就只能存储什么类型的数据类型
*
* 创建一个含有泛型的类
* 格式： public class GenericClass<E>{
*            private E name;
*            public E getName(){
*                   return name;
*            }
*            public void setName(E e){
*                   this.e=e;
*            }
*       }
* 创建对象时根据<E>里的E填的是什么来确定数据类型。
* 如果没有写上<E>默认为Object类型。
*
* 创建一个含有泛型的方法
* 格式：
* 修饰符 <E> 返回值类型 方法名（参数列表 <使用泛型>）{
*           方法调
* }
* 返回值类型，方法体中定义局部变量，都可以用泛型，不止参数列表。
* 含有泛型的方法，在调用泛型的时候确定泛型的数据类型。
* 传递什么类型的参数，泛型就是什么类型
*
* 创建含有泛型的接口
*
* 第一种实现方式：定义接口的实现类，实现接口并同时指定了接口的泛型
*
* 例如：public interface Iterator<e> {
*        E next();
*      }
*       Scanner类实现了Iterator接口，并指定了接口的泛型为String，所以重写next方法默认就是String
*      public final class Scanner implement Iterator<String>{
*          public String next(){}
*      }
*
* 第二种实现方式：接口使用说明字母标记泛型，实现类就使用说明字母标记泛型。类跟着接口走。
* 相当于定义了一个含有泛型的类，创建对象的时候确定泛型的类型。
* 例如：
* public interface List<E>{
*     boolean add(E e);
*     E get(int index);
* }
* public class ArrayList<e> implement List<e>{
*
* }
*
* 通配符基本使用
* 泛型的通配符：不知道使用说明类型来接受的时候，此时可以使用?,?表示位置通配符
* 此时只能接受数据，不能往该集合中存储数据。一旦使用类泛型的通配符，只能使用Object类中的共性方法，集合中的元素的自身方法无法使用。
* 泛型通配符使用规则：只能在作为方法的参数使用，不能穿件对象使用。
* 例如我们定义一个能遍历所有ArrayList的方法，因为我们不知道要接收的ArrayList使用了什么数据类型，所以可以在形参处写ArrayList<?> list
* 来接收任意数据类型的ArrayList集合。
*
* 泛型的上限限定格式： ? extend E 代表使用的泛型只能是E类型子类/本身
* 泛型的下限限定格式： ? super E 代表使用的泛型只能E类型父类/本身
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* */
public class 泛型 {
}
